

import base.KnowledgeBaseManager;

import static org.junit.Assert.*;

import java.util.ArrayList;

import junit.framework.Assert;

import logicaDePredicados.LogicOperatorFactory;
import logicaDePredicados.LogicPredicate;
import logicaDePredicados.Pair;
import logicaDePredicados.PredicateConstant;
import logicaDePredicados.PredicateVariable;
import logicaDePredicados.QuantifierStrategy;
import logicaDePredicados.Sentence;
import logicaDePredicados.SkolemFunction;

import org.junit.Before;
import org.junit.Test;

import exceptions.UnBalancedExpressionException;
import exceptions.UnDecidibleValueException;
import java.io.File;

/**
 * tested ok!
 * @author Francisco Gindre
 *
 */
public class QuantifierStrategyTest {
	private LogicPredicate<String> animal;
	private LogicPredicate<String> mammal;
	private PredicateConstant<String> perro;
	private PredicateConstant<String> helecho;
	private Sentence sentencia = new Sentence (new QuantifierStrategy());
	private LogicPredicate<String> dog;
	private PredicateVariable <String> x = new PredicateVariable<String >("X","X");
	private PredicateVariable <String> y = new PredicateVariable<String >("y","y");
	private PredicateVariable <String> z = new PredicateVariable<String >("z","z");
	private LogicPredicate<String> bird; 
	private LogicPredicate<Pair<String,String>> loves= new LogicPredicate<Pair<String,String>>("LOVES");
	private LogicPredicate<Pair<String,String>> hates= new LogicPredicate<Pair<String,String>>("HATES");
	private SkolemFunction<String, String> siblingOf = new SkolemFunction<String, String>("sibling-Of");
	private LogicPredicate<String>hasSibling = new LogicPredicate<String>("HASSIBILING");
	/**
	 * @throws Exception
	 */
	/**
	 * @throws Exception
	 */
	@Before
	public void setUp() throws Exception {
		animal = new LogicPredicate<String>("ANIMAL");
		mammal = new LogicPredicate<String>("MAMMAL");
		dog = new LogicPredicate<String>("DOG");
		bird =  new LogicPredicate<String>("BIRD");
		perro = new PredicateConstant<String>("perro","PERRO");
		helecho= new PredicateConstant<String>("helecho","HELECHO");
		
		animal.addTruthValue("perro",new Boolean (true));
		animal.addTruthValue("ganso",new Boolean (true));
		animal.addTruthValue("pato",new Boolean (true));
		animal.addTruthValue("zorro",new Boolean (true));
		animal.addTruthValue("gallo",new Boolean (true));
		animal.addTruthValue("gallina",new Boolean (true));
		animal.addTruthValue("pez",new Boolean (true));
		animal.addTruthValue("ballena",new Boolean (true));
	//	animal.addTruthValue("mesa",new Boolean (false));
	//	animal.addTruthValue("silla",new Boolean (false));
	//	animal.addTruthValue("balcon",new Boolean (false));
	//	animal.addTruthValue("termo",new Boolean (false));
		animal.addTruthValue("pitbull",new Boolean (true));
		animal.addTruthValue("chihuahua",new Boolean (true));
		animal.addTruthValue("terrier",new Boolean (true));
		animal.addTruthValue("sheppard",new Boolean (true));
		animal.addTruthValue("canario", true);
		animal.addTruthValue("colibrí", true);
		animal.addTruthValue("paloma", true);
		
		mammal.addTruthValue("perro",new Boolean (true));
		mammal.addTruthValue("ganso",new Boolean (false));
		mammal.addTruthValue("pato",new Boolean (false));
		mammal.addTruthValue("zorro",new Boolean (true));
		mammal.addTruthValue("gallo",new Boolean (false));
		mammal.addTruthValue("gallina",new Boolean (false));
		mammal.addTruthValue("pez",new Boolean (false));
		mammal.addTruthValue("ballena",new Boolean (true));
//		mammal.addTruthValue("mesa",new Boolean (false));
//		mammal.addTruthValue("silla",new Boolean (false));
//		mammal.addTruthValue("balcon",new Boolean (false));
//		mammal.addTruthValue("termo",new Boolean (false));
		mammal.addTruthValue("pitbull",new Boolean (true));
		mammal.addTruthValue("chihuahua",new Boolean (true));
		mammal.addTruthValue("terrier",new Boolean (true));
		mammal.addTruthValue("sheppard",new Boolean (true)); //16
		mammal.addTruthValue("canario", true);
		mammal.addTruthValue("colibrí", true);
		mammal.addTruthValue("paloma", true);
		
		dog.addTruthValue("perro",new Boolean (true));
		dog.addTruthValue("ganso",new Boolean (false));
		dog.addTruthValue("pato",new Boolean (false));
		dog.addTruthValue("zorro",new Boolean (false));
		dog.addTruthValue("gallo",new Boolean (false));
		dog.addTruthValue("gallina",new Boolean (false));
		dog.addTruthValue("pez",new Boolean (false));
		dog.addTruthValue("ballena",new Boolean (false));
//		dog.addTruthValue("mesa",new Boolean (false));
//		dog.addTruthValue("silla",new Boolean (false));
//		dog.addTruthValue("balcon",new Boolean (false));
//		dog.addTruthValue("termo",new Boolean (false));
		dog.addTruthValue("pitbull",new Boolean (true));
		dog.addTruthValue("chihuahua",new Boolean (true));
		dog.addTruthValue("terrier",new Boolean (true));
		dog.addTruthValue("sheppard",new Boolean (true));
		dog.addTruthValue("canario", false);
		dog.addTruthValue("colibrí", false);
		dog.addTruthValue("paloma", false);
		
		bird.addTruthValue("perro",new Boolean (false));
		bird.addTruthValue("ganso",new Boolean (true));
		bird.addTruthValue("pato",new Boolean (true));
		bird.addTruthValue("zorro",new Boolean (false));
		bird.addTruthValue("gallo",new Boolean (true));
		bird.addTruthValue("gallina",new Boolean (true));
		bird.addTruthValue("pez",new Boolean (false));
		bird.addTruthValue("ballena",new Boolean (true));
//		bird.addTruthValue("mesa",new Boolean (false));
//		bird.addTruthValue("silla",new Boolean (false));
//		bird.addTruthValue("balcon",new Boolean (false));
//		bird.addTruthValue("termo",new Boolean (false));
		bird.addTruthValue("pitbull",new Boolean (false));
		bird.addTruthValue("chihuahua",new Boolean (false));
		bird.addTruthValue("terrier",new Boolean (false));
		bird.addTruthValue("sheppard",new Boolean (false));
		bird.addTruthValue("canario", true);
		bird.addTruthValue("colibrí", true);
		bird.addTruthValue("paloma", true);


		loves.addTruthValue(new Pair<String, String>("John","Mary"), true);
		loves.addTruthValue(new Pair<String, String>("John","John"), true);
		loves.addTruthValue(new Pair<String, String>("John","Peter"), false);
		loves.addTruthValue(new Pair<String, String>("John","Julie"), true);
		loves.addTruthValue(new Pair<String, String>("Julie","Mary"), true);
		loves.addTruthValue(new Pair<String, String>("John","Mark"), true);
		loves.addTruthValue(new Pair<String, String>("John","Ursula"), false);
		loves.addTruthValue(new Pair<String, String>("Ursula","Mary"), false);
		loves.addTruthValue(new Pair<String, String>("Ursula","John"), false);
		loves.addTruthValue(new Pair<String, String>("Ursula","Mark"), false);
		loves.addTruthValue(new Pair<String, String>("Mary","John"), false);
		hates.addTruthValue(new Pair<String, String>("John","Mary"), false);
		hates.addTruthValue(new Pair<String, String>("John","Peter"), true);
		siblingOf.addValue("John", "Ursula");
		siblingOf.addValue("Ursula","John");
		hasSibling.addTruthValue("John", true);
		
		sentencia.add(LogicOperatorFactory.createEssentialQuantifier());
		sentencia.add(x);
		sentencia.add(LogicOperatorFactory.createEssentialQuantifier());
		sentencia.add(y);
//		sentencia.add(LogicOperatorFactory.createEssentialQuantifier());
//		sentencia.add(z);
		sentencia.add(LogicOperatorFactory.createNOT());
		sentencia.add(dog);
		sentencia.add(x);
		sentencia.add(LogicOperatorFactory.createOR());
		sentencia.add(LogicOperatorFactory.createNOT());
		sentencia.add(bird);
		sentencia.add(y);
		sentencia.add(LogicOperatorFactory.createOR());
		
		sentencia.add(animal);
		sentencia.add(x);
		sentencia.add(LogicOperatorFactory.createAND());
		sentencia.add(LogicOperatorFactory.createNOT());
		sentencia.add(bird);
		sentencia.add(x);
		sentencia.add(LogicOperatorFactory.createAND());
		sentencia.add(LogicOperatorFactory.createNOT());
		sentencia.add(mammal);
		sentencia.add(y);
		System.out.println(sentencia);
		
	}
	
	@Test
	public void testSentence() throws UnBalancedExpressionException, UnDecidibleValueException, Exception {
                KnowledgeBaseManager.storeLogicPredicate(animal,new File("./sampleBase.yap"));
                KnowledgeBaseManager.storeLogicPredicate(mammal,new File("./sampleBase.yap"));
                KnowledgeBaseManager.storeLogicPredicate(dog,new File("./sampleBase.yap"));
                KnowledgeBaseManager.storeLogicPredicate(bird,new File("./sampleBase.yap"));


//		ArrayList<Pair<LogicPredicate<?>,PredicateVariable<?>>> predicados = new ArrayList<Pair<LogicPredicate<?>,PredicateVariable<?>>>();
//		predicados=new QuantifierStrategy().getDependentPredicates(sentencia);
//		for (Pair<LogicPredicate<?>, PredicateVariable<?>> pair : predicados) {
//			System.out.println(pair.getFirstArgument().getName()+"  "+ pair.getSecondArgument().getName());
//			
//		}
//		
//		QuantifierStrategy strat= new QuantifierStrategy();
//		strat.parseSentence(sentencia);
//		ArrayList<Pair<LogicPredicate<?>,PredicateVariable<?>>>  dependent = strat.getDependentPredicates(sentencia);
//		
//		ArrayList<ArrayList<PredicateConstant<?>>> combinatorial =strat.makeVariableValueList(dependent);
//		Assert.assertEquals(2, combinatorial.size());
//		Assert.assertEquals(0, strat.indexMap.get(x).intValue());
//		Assert.assertEquals(1, strat.indexMap.get(y).intValue());
//		Assert.assertEquals(20, combinatorial.get(0).size());
//		Assert.assertEquals(20, combinatorial.get(1).size());
//		strat.values= new PredicateConstant<?>[combinatorial.size()];
//		
//		strat.combine(0, 0, combinatorial);
//		Assert.assertEquals((combinatorial.get(0).size())*(combinatorial.get(1).size()), strat.combinatorialSet.size());
		Assert.assertEquals(true, sentencia.parse());
	}

	

}
